package cn.monkey.family.server.domain.uc.user;

import cn.monkey.family.data.crud.repository.ExampleQueryRequestRepository;
import cn.monkey.family.data.crud.repository.QueryRequestRepository;
import cn.monkey.family.data.uc.user.User;
import cn.monkey.family.data.uc.user.UserQueryRequest;
import com.google.common.base.Strings;
import org.springframework.data.domain.*;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.query.ListQueryByExampleExecutor;

import java.util.List;
import java.util.Optional;

@NoRepositoryBean
public interface UserRepository extends ExampleQueryRequestRepository<User, String, UserQueryRequest>,
        ListQueryByExampleExecutor<User> {

    @Override
    default Example<User> example(UserQueryRequest queryRequest) {
        User user = new User();
        ExampleMatcher matcher = ExampleMatcher.matching();
        String account = queryRequest.getAccount();
        boolean hasProperty = false;
        if (!Strings.isNullOrEmpty(account)) {
            matcher = matcher.withMatcher("account", ExampleMatcher.GenericPropertyMatchers.contains());
            user.setAccount(account);
            hasProperty = true;
        }
        String mobile = queryRequest.getMobile();
        if (!Strings.isNullOrEmpty(mobile)) {
            matcher = matcher.withMatcher("mobile", ExampleMatcher.GenericPropertyMatchers.exact());
            user.setMobile(mobile);
            hasProperty = true;
        }
        String email = queryRequest.getEmail();
        if (!Strings.isNullOrEmpty(email)) {
            matcher = matcher.withMatcher("email", ExampleMatcher.GenericPropertyMatchers.exact());
            user.setEmail(email);
            hasProperty = true;
        }
        return hasProperty ? Example.of(user, matcher) : Example.of(user);
    }

    default List<User> findByAccountOrMobileOrEmail(String data) {
        User user = new User();
        user.setMobile(data);
        user.setAccount(data);
        user.setEmail(data);
        return this.findAll(Example.of(user, ExampleMatcher.matchingAny()
                .withMatcher("mobile", ExampleMatcher.GenericPropertyMatchers.exact())
                .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.exact())
                .withMatcher("email", ExampleMatcher.GenericPropertyMatchers.exact())
        ));
    }

    default Optional<User> findOneByMobile(String mobile) {
        return this.findOneByQueryRequest(UserQueryRequest.builder().mobile(mobile).build());
    }
}

